package com.client;

import java.awt.Color;
import java.util.Map;
import java.util.Map.Entry;

import util.Util;

import com.client.listeners.DoodleListener;
import com.exception.IllegalPackageException;
import com.packages.ServerPackageHandler;
import com.sendables.ChatMessage;
import com.sendables.Circle;
import com.sendables.Cursor;
import com.sendables.DoodlePoint;
import com.sendables.Line;
import com.sendables.MultiPointLine;
import com.sendables.Sendable;
import com.sendables.Square;
import com.wrappers.IntegerWrapper;
import com.wrappers.MapWrapper;
import com.wrappers.Pair;
import com.wrappers.Returnable;
import com.wrappers.SendableWrapper;

public class MessageHandler extends Thread {
	private ServerPackageHandler	sph;
	private DoodleListener			dl;
	private Monitor					m;
	private int						status;
	private GUIMonitor				guim;

	public MessageHandler(Monitor m, GUIMonitor guim, ServerPackageHandler sph, DoodleListener dl)
	{
		this.dl = dl;
		this.sph = sph;
		this.m = m;
		this.guim = guim;
		status = -1;
	}

	@SuppressWarnings("unchecked")
	public void run()
	{
		while (true)
		{
			byte[] b = m.get();
			status = m.getStatus(status);
			int[] offset = new int[] { 4 };
			int maskedStatus = status | b[offset[0]];
			Returnable r = null;
			try
			{
				r = sph.parse(b);
			} catch (IllegalPackageException e)
			{
				e.printStackTrace();
			}
			switch (maskedStatus)
			{
				case Monitor.AWAIT_ID_ANS:
					int id = ((IntegerWrapper) r).unwrap();
					dl.setId(id);
					m.setStatus(Monitor.SEND_ROOM_LIST_REQ);
					break;
				case Monitor.AWAITING_ROOM_LIST_ANS:
					Map<Integer, String> result = ((MapWrapper) r).unwrap();
					guim.setRoomList(result);
					m.setStatus(Monitor.AWAITING_USER_JOIN_OR_CREATE);
					break;
				case Monitor.AWAITING_JOIN_ROOM_ANS:
					System.out.println("Tog emot room join asn från server");
					Pair<Integer, Integer> joinAns = (Pair<Integer, Integer>) r;
					if (joinAns == null)
					{
						m.setStatus(Monitor.AWAITING_USER_ROOM_SELECT);
					} else
					{
						m.setStatus(Monitor.AWAITING_DRAWABLE);
						System.out.println("mdoe: drawable");
						Sendable.c = new Color(joinAns.getFirst());
					}
					break;
				case Monitor.AWAITING_DRAWABLE:
					if ((b[offset[0] + 1] & Sendable.LINE) != 0)
					{
						Line l = (Line) ((SendableWrapper) r).unwrap();
						m.postTempBuffer(l, l.getId(), Sendable.LINE);
					} else if ((b[offset[0] + 1] & Sendable.MULTI_POINT_LINE) != 0)
					{
						MultiPointLine mpl = (MultiPointLine) ((SendableWrapper) r).unwrap();
						m.removeFromTempBuffer(mpl.getId(), Sendable.LINE);
						m.postUndoBuffer(mpl.getId(), mpl);
					} else if ((b[offset[0] + 1] & Sendable.SQUARE) != 0)
					{
						Square s = (Square) ((SendableWrapper) r).unwrap();
						if (s.isTemporary())
						{
							m.postTempBuffer(s, s.getId(), Sendable.SQUARE);
						} else
						{
							m.removeFromTempBuffer(s.getId(), Sendable.SQUARE);
							m.postUndoBuffer(s.getId(), s);
						}

					} else if ((b[offset[0] + 1] & Sendable.CIRCLE) != 0)
					{
						Circle s = (Circle) ((SendableWrapper) r).unwrap();
						if (s.isTemporary())
						{
							m.postTempBuffer(s, s.getId(), Sendable.CIRCLE);
						} else
						{
							m.removeFromTempBuffer(s.getId(), Sendable.CIRCLE);
							m.postUndoBuffer(s.getId(), s);
						}
					}

					else if (b[offset[0] + 1] == Sendable.CURSOR)
					{
						Cursor l = (Cursor) ((SendableWrapper) r).unwrap();
						m.setCursor(l);
					} else if (b[offset[0] + 1] == Sendable.CHAT_MESSAGE)
					{
						ChatMessage cm = (ChatMessage) ((SendableWrapper) r).unwrap();
						m.getTextArea().putContent(cm.getContent());
					}
					break;
				case Monitor.AWAITING_USER_ROOM_CREATE_ANS:
					Pair<Integer, String> roomAns = (Pair<Integer, String>) r;
					if (roomAns == null)
					{
						m.setStatus(Monitor.AWAITING_USER_JOIN_OR_CREATE);
						System.out.println("Room couldnt be created.");
					} else
					{
						System.out
								.println("Room created! Name: " + roomAns.getSecond() + ", id: " + roomAns.getFirst());
						m.setStatus(Monitor.SEND_ROOM_LIST_REQ);
					}
					break;
				default:
					System.out.println("Unexpected package begin {");
					Util.print(b, " ");
					System.out.println("} package ended");
			}
			status = m.getStatus();
		}
	}
}
